﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Application.Services;
using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using KelonProud.Mvc;
using KelonProud.TableManagement.Domain;
using KelonProud.TableManagement.Dtos.DataBase;
using KelonProud.TableManagement.Dtos.Table;
using KelonProud.TableManagement.Managers;
using Microsoft.EntityFrameworkCore;

namespace KelonProud.TableManagement.Services
{
    public interface ITableCategoryAppService: IAsyncCrudAppService<TableCategoryOutput, int, PagedResultRequestDto, TableCategoryInput, TableCategoryOutput>
    {
        Task<IEnumerable<object>> GetCategoryTreeJson(bool isAll = true);
    }

    public class TableCategoryAppService: KelonProudAsyncCrudAppService<TableCategory, TableCategoryOutput, int, PagedResultRequestDto, TableCategoryInput, TableCategoryOutput>, ITableCategoryAppService
    {
        private readonly TableCategoryManager _tableCategoryManager;

        public TableCategoryAppService(IRepository<TableCategory, int> repository, TableCategoryManager tableCategoryManager) : base(repository)
        {
            _tableCategoryManager = tableCategoryManager;
        }

        public override Task<TableCategoryOutput> Save(TableCategoryInput input)
        {
            var category = _tableCategoryManager.GetById(input.Id) ?? new TableCategory() { };

            var parent = _tableCategoryManager.GetById(input.ParentId.ToInt32(0));

            category.Code = input.Code;
            category.Name = input.Name;
            category.ParentId = parent?.Id;
            category.Level = parent == null ? 1 : parent.Level + 1;
            category.Order = parent == null ? 1 : (parent.Children.Any() ? parent.Children.Max(m => m.Order) + 1 : 1);

            if (parent != null)
            {
               if(parent.IdPath.Contains("-" + category.Id + "-")) 
                    throw new Exception("您不能选择自己的下级分类作为上级。");
            }

            category = _tableCategoryManager.Save(category);
            category.IdPath = parent != null ? parent.IdPath + category.Id + "-" : "-" + category.Id + "-";
            category.NamePath = parent != null ? parent.NamePath + " > " + category.Name : category.Name;
            SetChildNamePath(category);

            return Task.FromResult(category.MapTo<TableCategoryOutput>());
        }

        public override Task Delete(EntityDto<int> input)
        {
            try
            {
                var result = base.Delete(input);
                 UnitOfWorkManager.Current.SaveChanges();
                 return result;
            }
            catch 
            {
                throw new Exception("该节点下已有其他分类或者表格，不能被删除");
            }
        }

        public async Task<IEnumerable<object>> GetCategoryTreeJson(bool isAll = true)
        {
            var tableCategorys = await _tableCategoryManager.Query.OrderBy(o => o.Id).ToListAsync();

            var result =  tableCategorys.Select(s => new
            {
                Id =s.Id.ToString(),
                PId = s.ParentId.HasValue?s.ParentId.ToString():"-1",
                Name = s.Name,
                Code=s.Code,
                FullName = s.NamePath,
                open = false
            }).ToList();

            result.Add(new
            {
                Id = "-1",
                PId =  "-2",
                Name = isAll?"全部分类":"无",
                Code = "-1",
                FullName = "",
                open = false
            });

            return result;
        }

        private void SetChildNamePath(TableCategory category)
        {
            category.Children?.Each(e =>
            {
                e.IdPath = category.IdPath + e.Id + "-";
                e.NamePath = category.NamePath + " > " + e.Name;
                e.Level = (byte)(category.Level + 1);
                SetChildNamePath(e);
            });
        }

    }
}
